package com.agileboot.api.controller.common;

import com.agileboot.api.customize.service.AppLoginService;
import com.agileboot.api.customize.service.JwtTokenService;
import com.agileboot.common.core.base.BaseController;
import com.agileboot.common.core.dto.ResponseDTO;
import com.agileboot.common.utils.http.HttpTemplate;
import com.agileboot.domain.common.dto.WxTokenDTO;
import com.agileboot.domain.system.user.db.SysUserEntity;
import com.agileboot.domain.system.user.dto.UserDTO;
import com.agileboot.domain.system.user.dto.WxUserInfoDTO;
import com.agileboot.infrastructure.user.app.AppLoginUser;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotBlank;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 调度日志操作处理
 *
 * @author ruoyi
 */
@RestController
@RequiredArgsConstructor
public class LoginController extends BaseController {

    @Value("${wxInfo.APP_ID}")
    private String appid;

    @Value("${wxInfo.SECRET_KEY}")
    private String secret;

    private final JwtTokenService jwtTokenService;

    private final AppLoginService appLoginService;



    /**
     * 访问首页，提示语
     */
//    @PreAuthorize("hasAuthority('annie')")
    @GetMapping("/")
    public ResponseDTO<?> appLogin() {
        return ResponseDTO.ok();
    }

    /**
     * 小程序登录
     * @param code
     * @return
     * @throws ParseException
     * @throws JsonProcessingException
     */
    @GetMapping("/login")
    public ResponseDTO<WxTokenDTO> appLogin(@Validated @RequestParam @NotBlank(message = "code不能为空") String code) throws JsonProcessingException {
//        String token = jwtTokenService.generateToken(MapUtil.of("token", "user1"));
        SysUserEntity userEntity = appLoginService.loginAppUser(code);
        UserDTO userDTO = new UserDTO(userEntity);
        AppLoginUser appLoginUser = new AppLoginUser(userEntity.getUserId(), false, userEntity.getOpenId());
        appLoginUser.setAutoRefreshCacheTime(System.currentTimeMillis()
                + TimeUnit.MINUTES.toMillis(jwtTokenService.getAutoRefreshTime()));
        String token = jwtTokenService.createTokenAndPutAppUserInCache(appLoginUser);
        return ResponseDTO.ok(new WxTokenDTO(token,userDTO));
    }


    /**
     * 获取手机号
     * @param code
     * @return
     */
    @GetMapping("/getPhone")
    public ResponseDTO<JSONObject> getPhone(@RequestParam String code){
        if("".equals(code)||code==null){
            return ResponseDTO.build(null,10502,"code不能为空");
        }
        String result= HttpTemplate.httpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"+"&appid="+appid+"&secret="+secret);
        JSONObject jsonObject= JSONObject.parseObject(result);
        if(jsonObject.get("errcode")!=null){
            String errCode= jsonObject.get("errcode").toString();
            if(getAccessTokenMsg(errCode)!=null) return ResponseDTO.build(null,10503,getAccessTokenMsg(errCode));
            return ResponseDTO.build(null,10504,"获取accessToken,错误码："+errCode);
        }
        Map<String, Object> requestBody = new HashMap<>();
        String accessToken=jsonObject.get("access_token").toString();
        requestBody.put("code",code);
//        requestBody.put("access_token",accessToken);
        //获取手机号的接口 post方式-json格式
        String resultPhone= HttpTemplate.httpPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+accessToken,requestBody);
        JSONObject jsonObjectPhone= JSONObject.parseObject(resultPhone);
        String errCode= jsonObjectPhone.get("errcode").toString();
        if(!"0".equals(errCode)){
            if(getPhoneMsg(errCode)!=null) return ResponseDTO.build(null,10505,getPhoneMsg(errCode));
            return ResponseDTO.build(null,10505,jsonObjectPhone.get("errmsg").toString());
        }
        System.out.println(errCode);
        return ResponseDTO.ok(jsonObjectPhone);

    }

    /**
     * 获取小程序用户信息
     * @return
     */
    @GetMapping("/getUserInfo")
    public ResponseDTO<WxUserInfoDTO> getAppUserInfo(){
        WxUserInfoDTO wxUserInfoDTO = appLoginService.getWxUserInfo();
        return ResponseDTO.ok(wxUserInfoDTO);
    }

    private Long timeLong() throws ParseException {
        // 定义日期时间字符串和格式
        String dateStr = "2024-09-04 22:43:07";
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 解析日期时间字符串
            Date date = formatter.parse(dateStr);

            // 获取时间戳（毫秒）
            long timestamp = date.getTime();

            // 输出时间戳
            return timestamp;
    }

    /**
     * 获取手机号的错误code提示
     * @param errCode
     * @return
     */
    private String getPhoneMsg(String errCode){
        if(errCode.equals("40029")){
            return "code无效";
        }
        if(errCode.equals("-1")){
            return "系统繁忙";
        }
        if(errCode.equals("40013")){
            return "请求appid身份与获取code的小程序appid不匹配";
        }
        if(errCode.equals("45011")){
            return "API 调用太频繁，请稍候再试";
        }
        return null;
    }

    /**
     * 获取access_token 的错误code提示
     * @param errCode
     * @return
     */
    private String getAccessTokenMsg(String errCode){
        if(errCode.equals("40001")){
            return " AppSecret 错误，或者 access_token 无效";
        }
        if(errCode.equals("-1")){
            return "系统繁忙";
        }
        if(errCode.equals("40013")){
            return "不合法的 AppID";
        }
        if(errCode.equals("40002")){
            return "不合法的凭证类型";
        }
        if(errCode.equals("40125")){
            return "不合法的 secret";
        }
        if(errCode.equals("40164")){
            return "调用接口的IP地址不在白名单中";
        }
        if(errCode.equals("41004")){
            return "缺少 secret 参数";
        }
        return null;
    }
}
